package com.cib.icarus.core.enums;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;


/**
 * 常见的日期格式枚举，并且包含了一些便捷操作的方法
 *
 * @author goomba
 */
public enum IcarusDateFormatEnum {

    YMD_SHORT("yyyyMMdd"),
    YMD_LONG("yyyy-MM-dd"),
    YMD_CHS("yyyy年MM月dd日"),

    YMD_HMS_SHORT("yyyyMMddHHmmss"),
    YMD_HMS_MEDIUM("yyyyMMdd HH:mm:ss"),
    YMD_HMS_LONG("yyyy-MM-dd HH:mm:ss"),
    YMD_HMS_CHS("yyyy年MM月dd日 HH时mm分ss秒"),


    YMD_HMS_MIS_SHORT("yyyyMMdd HHmmssSSS"),
    YMD_HMS_MIS_MEDIUM("yyyyMMdd HH:mm:ss.SSS"),
    YMD_HMS_MIS_LONG("yyyy-MM-dd HH:mm:ss.SSS"),
    YMD_HMS_MIS_CHS("yyyy年MM月dd日 HH时mm分ss秒SSS毫秒"),
    ;
    private final String dateFormat;

    private static final ZoneOffset TIME_ZONE = ZoneOffset.of("+8");

    IcarusDateFormatEnum(String dateFormat) {
        this.dateFormat = dateFormat;
    }

    public String getDateFormat() {
        return dateFormat;
    }


    /**
     * 该方法使用Java 8的DateTimeAPI来获取当前系统日期和时间，并将其格式化为预定义的日期格式
     * 主要用于需要以字符串形式获取当前日期的场景
     *
     * @return 当前日期的字符串表示，格式为预定义的dateFormat
     */
    public String getCurrentDateStr() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateFormat));
    }


    /**
     * 将给定的时间戳转换为指定格式的日期字符串
     *
     * @param timestamp 时间戳，单位为毫秒
     * @return 格式化的日期字符串
     * @throws IllegalArgumentException 如果传入的时间戳为null，则抛出此异常
     */
    public String getDateStr(Long timestamp) {
        if (null == timestamp) {
            throw new IllegalArgumentException("timestamp must not be null!");
        }
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TIME_ZONE)
                .format(DateTimeFormatter.ofPattern(dateFormat));
    }

    /**
     * 将日期字符串转换为时间戳
     *
     * @param dateStr 日期字符串，其格式由dateFormat定义
     * @return 对应的时间戳（毫秒）
     */
    public Long getTimestamp(String dateStr) {
        // 判断是否按本地日期格式处理
        if (isLocalDateDealFormat()) {
            // 如果是本地日期格式，解析日期字符串为LocalDate对象
            LocalDate localDate = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(dateFormat));
            // 将LocalDate对象转换为当天开始的时间，并转换为指定时区的时间戳
            return localDate.atStartOfDay().atZone(TIME_ZONE).toInstant().toEpochMilli();
        }

        // 如果不是本地日期格式，解析日期字符串为LocalDateTime对象
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(dateFormat));
        // 将LocalDateTime对象转换为指定时区的时间戳
        return localDateTime.atZone(TIME_ZONE).toInstant().toEpochMilli();
    }

    /**
     * 判断当前日期格式是否为本地交易日期格式
     * <p>
     * 该方法用于确定当前日期格式是否符合本地交易日期的常见表示形式
     * 主要通过比较当前格式与预定义的几种本地交易日期格式是否相等来判断
     *
     * @return 如果当前格式为本地交易日期格式，则返回true；否则返回false
     */
    public boolean isLocalDateDealFormat() {
        return this.equals(YMD_SHORT) || this.equals(YMD_LONG) || this.equals(YMD_CHS);
    }


}
